package com.freecloud.framework.plugin.feign;

import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.TypeAdapter;
import feign.FeignException;
import feign.Response;
import feign.Util;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Type;
import java.util.Collections;

import static feign.Util.ensureClosed;

/**
 * @Author: maomao
 * @Date: 2019-08-19 10:34
 */
public class FeignDecoder implements Decoder {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private final Gson gson;

    public FeignDecoder(Iterable<TypeAdapter<?>> adapters) {
        this(GsonFactory.create(adapters));
    }

    public FeignDecoder() {
        this(Collections.<TypeAdapter<?>>emptyList());
    }

    public FeignDecoder(Gson gson) {
        this.gson = gson;
    }


    @Override
    public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {

        logger.info("FeignDecoder type : {} \r\n {}",response);

        if (response.status() == 404){
            return Util.emptyValueOf(type);
        }
        if (response.body() == null){
            return null;
        }

        if("java.lang.String".equals(type.getTypeName())){
            return response.body().toString();
        }

        logger.info(type.getTypeName());

        Reader reader = response.body().asReader();
        try {
            return gson.fromJson(reader, type);
        } catch (JsonIOException e) {
            if (e.getCause() != null && e.getCause() instanceof IOException) {
                throw IOException.class.cast(e.getCause());
            }
            throw e;
        } finally {
            ensureClosed(reader);
        }
    }
}
